package com.gitee.sop.order.pay.util;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.*;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author Admin
 */
public class XmlUtils {

    public static String map2xmlBody(Map<String, Object> vo, String rootElement) {
        Document doc = DocumentHelper.createDocument();
        Element body = DocumentHelper.createElement(rootElement);
        doc.add(body);
        buildMap2xmlBody(body, vo);
        return doc.asXML();
    }

    private static void buildMap2xmlBody(Element body, Map<String, Object> vo) {
        if (vo != null) {
            Iterator<String> it = vo.keySet().iterator();
            while (it.hasNext()) {
                String key = (String) it.next();
                if (StringUtils.isNotEmpty(key)) {
                    Object obj = vo.get(key);
                    Element element = DocumentHelper.createElement(key);
                    if (obj != null) {
                        if ((obj instanceof String)) {
                            element.setText((String) obj);
                        } else if (((obj instanceof Character)) || ((obj instanceof Boolean)) || ((obj instanceof Number)) || ((obj instanceof BigInteger)) || ((obj instanceof BigDecimal))) {
                            Attribute attr = DocumentHelper.createAttribute(element, "type", obj.getClass().getCanonicalName());
                            element.add(attr);
                            element.setText(String.valueOf(obj));
                        } else if ((obj instanceof Map)) {
                            Attribute attr = DocumentHelper.createAttribute(element, "type", Map.class.getCanonicalName());
                            element.add(attr);
                            buildMap2xmlBody(element, (Map) obj);
                        }
                    }
                    body.add(element);
                }
            }
        }
    }

    public static Map xmlBody2map(String xml, String rootElement)
            throws DocumentException {
        Document doc = DocumentHelper.parseText(xml);
        Element body = (Element) doc.selectSingleNode("/" + rootElement);
        Map vo = buildXmlBody2map(body);
        return vo;
    }

    private static Map buildXmlBody2map(Element body) {
        Map vo = new HashMap();
        if (body != null) {
            List<Element> elements = body.elements();
            for (Element element : elements) {
                String key = element.getName();
                if (StringUtils.isNotEmpty(key)) {
                    String type = element.attributeValue("type", "java.lang.String");
                    String text = element.getText().trim();
                    Object value = null;
                    if (String.class.getCanonicalName().equals(type)) {
                        value = text;
                    } else if (Character.class.getCanonicalName().equals(type)) {
                        value = new Character(text.charAt(0));
                    } else if (Boolean.class.getCanonicalName().equals(type)) {
                        value = new Boolean(text);
                    } else if (Short.class.getCanonicalName().equals(type)) {
                        value = Short.valueOf(Short.parseShort(text));
                    } else if (Integer.class.getCanonicalName().equals(type)) {
                        value = Integer.valueOf(Integer.parseInt(text));
                    } else if (Long.class.getCanonicalName().equals(type)) {
                        value = Long.valueOf(Long.parseLong(text));
                    } else if (Float.class.getCanonicalName().equals(type)) {
                        value = Float.valueOf(Float.parseFloat(text));
                    } else if (Double.class.getCanonicalName().equals(type)) {
                        value = Double.valueOf(Double.parseDouble(text));
                    } else if (BigInteger.class.getCanonicalName().equals(type)) {
                        value = new BigInteger(text);
                    } else if (BigDecimal.class.getCanonicalName().equals(type)) {
                        value = new BigDecimal(text);
                    } else if (Map.class.getCanonicalName().equals(type)) {
                        value = buildXmlBody2map(element);
                    }
                    vo.put(key, value);
                }
            }
        }
        return vo;
    }


    public static String map2XmlString(Map<String, String> map) {
        String xmlResult = "";

        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        for (String key : map.keySet()) {
            System.out.println(key + "========" + map.get(key));

            String value = "<![CDATA[" + map.get(key) + "]]>";
            sb.append("<" + key + ">" + value + "</" + key + ">");
            sb.append("\n");
        }
        sb.append("</xml>");
        xmlResult = sb.toString();

        return xmlResult;
    }

    /**
     * @param xml
     * @return Map
     * @description 将xml字符串转换成map
     */
    public static Map<String, String> readStringXmlOut(String xml) {
        Map<String, String> map = new HashMap<String, String>();
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(xml); // 将字符串转为XML
            Element rootElt = doc.getRootElement(); // 获取根节点
            @SuppressWarnings("unchecked")
            List<Element> list = rootElt.elements();// 获取根节点下所有节点
            for (Element element : list) { // 遍历节点
                map.put(element.getName(), element.getText()); // 节点的name为map的key，text为map的value
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}
